/**
 * 渲染引擎核心
 * 高性能的Canvas 2D渲染系统
 */

// 渲染配置接口
export interface RenderConfig {
  width?: number
  height?: number
  backgroundColor?: string
  pixelRatio?: number
  antialias?: boolean
  preserveDrawingBuffer?: boolean
}

// 图层数据接口
export interface LayerData {
  id: string
  type: string
  visible: boolean
  position: { x: number; y: number }
  scale: { x: number; y: number }
  rotation: number
  opacity: number
  zIndex: number
  assetId?: string
  url?: string
}

// 渲染统计接口
export interface RenderStats {
  fps: number
  frameTime: number
  drawCalls: number
  layersRendered: number
  cacheHits: number
  cacheMisses: number
}

// 图片缓存项
interface CacheItem {
  image: HTMLImageElement
  lastUsed: number
  loading: boolean
}

// 渲染引擎类
export class RenderEngine {
  private canvas: HTMLCanvasElement
  private ctx: CanvasRenderingContext2D
  private config: Required<RenderConfig>
  private imageCache = new Map<string, CacheItem>()
  private maxCacheSize = 100
  private stats: RenderStats = {
    fps: 0,
    frameTime: 0,
    drawCalls: 0,
    layersRendered: 0,
    cacheHits: 0,
    cacheMisses: 0
  }
  private frameStartTime = 0
  private frameCount = 0
  private lastFpsUpdate = 0
  
  constructor(canvas: HTMLCanvasElement, config: RenderConfig = {}) {
    this.canvas = canvas
    const ctx = canvas.getContext('2d')
    if (!ctx) {
      throw new Error('无法获取2D渲染上下文')
    }
    this.ctx = ctx
    
    // 设置默认配置
    this.config = {
      width: config.width ?? 800,
      height: config.height ?? 600,
      backgroundColor: config.backgroundColor ?? '#f0f0f0',
      pixelRatio: config.pixelRatio ?? (window.devicePixelRatio || 1),
      antialias: config.antialias ?? true,
      preserveDrawingBuffer: config.preserveDrawingBuffer ?? false
    }
    
    this.setupCanvas()
  }
  
  // 设置画布
  private setupCanvas() {
    const { width, height, pixelRatio } = this.config
    
    // 设置画布实际尺寸
    this.canvas.width = width * pixelRatio
    this.canvas.height = height * pixelRatio
    
    // 设置画布显示尺寸
    this.canvas.style.width = `${width}px`
    this.canvas.style.height = `${height}px`
    
    // 缩放上下文以匹配设备像素比
    this.ctx.scale(pixelRatio, pixelRatio)
    
    // 设置抗锯齿
    if (this.config.antialias) {
      this.ctx.imageSmoothingEnabled = true
      this.ctx.imageSmoothingQuality = 'high'
    }
  }
  
  // 渲染主函数
  render(layers: LayerData[], showGrid = false, gridSize = 20) {
    this.frameStartTime = performance.now()
    this.stats.drawCalls = 0
    this.stats.layersRendered = 0
    
    // 清空画布
    this.clear()
    
    // 绘制网格（如果启用）
    if (showGrid) {
      this.drawGrid(gridSize)
    }
    
    // 按z-index排序图层
    const sortedLayers = [...layers].sort((a, b) => a.zIndex - b.zIndex)
    
    // 渲染可见图层
    for (const layer of sortedLayers) {
      if (layer.visible && layer.opacity > 0) {
        this.renderLayer(layer)
        this.stats.layersRendered++
      }
    }
    
    // 更新性能统计
    this.updateStats()
  }
  
  // 清空画布
  private clear() {
    this.ctx.fillStyle = this.config.backgroundColor
    this.ctx.fillRect(0, 0, this.config.width, this.config.height)
    this.stats.drawCalls++
  }
  
  // 绘制网格
  private drawGrid(gridSize: number) {
    this.ctx.save()
    this.ctx.strokeStyle = '#e0e0e0'
    this.ctx.lineWidth = 1
    this.ctx.globalAlpha = 0.5
    
    // 垂直线
    for (let x = 0; x <= this.config.width; x += gridSize) {
      this.ctx.beginPath()
      this.ctx.moveTo(x, 0)
      this.ctx.lineTo(x, this.config.height)
      this.ctx.stroke()
    }
    
    // 水平线
    for (let y = 0; y <= this.config.height; y += gridSize) {
      this.ctx.beginPath()
      this.ctx.moveTo(0, y)
      this.ctx.lineTo(this.config.width, y)
      this.ctx.stroke()
    }
    
    this.ctx.restore()
    this.stats.drawCalls += 2
  }
  
  // 渲染单个图层
  private renderLayer(layer: LayerData) {
    this.ctx.save()
    
    // 设置透明度
    this.ctx.globalAlpha = layer.opacity / 100
    
    // 应用变换
    this.applyTransform(layer)
    
    // 根据图层类型渲染
    switch (layer.type) {
      case 'image':
      case 'character':
      case 'scene':
        this.renderImageLayer(layer)
        break
      case 'text':
        this.renderTextLayer(layer)
        break
      case 'shape':
        this.renderShapeLayer(layer)
        break
      default:
        this.renderPlaceholder(layer)
    }
    
    this.ctx.restore()
    this.stats.drawCalls++
  }
  
  // 应用变换
  private applyTransform(layer: LayerData) {
    const { position, scale, rotation } = layer
    
    // 移动到图层位置
    this.ctx.translate(position.x, position.y)
    
    // 旋转
    if (rotation !== 0) {
      this.ctx.rotate((rotation * Math.PI) / 180)
    }
    
    // 缩放
    if (scale.x !== 1 || scale.y !== 1) {
      this.ctx.scale(scale.x, scale.y)
    }
  }
  
  // 渲染图片图层
  private renderImageLayer(layer: LayerData) {
    if (!layer.url && !layer.assetId) {
      this.renderPlaceholder(layer)
      return
    }
    
    const imageUrl = layer.url || this.getAssetUrl(layer.assetId!)
    if (!imageUrl) {
      this.renderPlaceholder(layer)
      return
    }
    
    const image = this.getImage(imageUrl)
    if (image && image.complete && image.naturalWidth > 0) {
      const width = image.naturalWidth
      const height = image.naturalHeight
      
      // 居中绘制
      this.ctx.drawImage(image, -width / 2, -height / 2, width, height)
      this.stats.cacheHits++
    } else {
      this.renderPlaceholder(layer)
      this.stats.cacheMisses++
    }
  }
  
  // 渲染文本图层
  private renderTextLayer(layer: LayerData) {
    // TODO: 实现文本渲染
    this.renderPlaceholder(layer, '文本')
  }
  
  // 渲染形状图层
  private renderShapeLayer(layer: LayerData) {
    // TODO: 实现形状渲染
    this.renderPlaceholder(layer, '形状')
  }
  
  // 渲染占位符
  private renderPlaceholder(layer: LayerData, text?: string) {
    const size = 100
    const halfSize = size / 2
    
    // 绘制边框
    this.ctx.strokeStyle = '#ccc'
    this.ctx.lineWidth = 2
    this.ctx.strokeRect(-halfSize, -halfSize, size, size)
    
    // 绘制对角线
    this.ctx.beginPath()
    this.ctx.moveTo(-halfSize, -halfSize)
    this.ctx.lineTo(halfSize, halfSize)
    this.ctx.moveTo(halfSize, -halfSize)
    this.ctx.lineTo(-halfSize, halfSize)
    this.ctx.stroke()
    
    // 绘制文本
    if (text || layer.type) {
      this.ctx.fillStyle = '#666'
      this.ctx.font = '12px Arial'
      this.ctx.textAlign = 'center'
      this.ctx.textBaseline = 'middle'
      this.ctx.fillText(text || layer.type, 0, 0)
    }
  }
  
  // 获取图片
  private getImage(url: string): HTMLImageElement | null {
    let cacheItem = this.imageCache.get(url)
    
    if (!cacheItem) {
      // 创建新的缓存项
      cacheItem = {
        image: new Image(),
        lastUsed: Date.now(),
        loading: true
      }
      
      cacheItem.image.onload = () => {
        cacheItem!.loading = false
      }
      
      cacheItem.image.onerror = () => {
        cacheItem!.loading = false
        console.warn(`图片加载失败: ${url}`)
      }
      
      cacheItem.image.src = url
      this.imageCache.set(url, cacheItem)
      
      // 清理缓存
      this.cleanupCache()
    } else {
      // 更新使用时间
      cacheItem.lastUsed = Date.now()
    }
    
    return cacheItem.loading ? null : cacheItem.image
  }
  
  // 清理图片缓存
  private cleanupCache() {
    if (this.imageCache.size <= this.maxCacheSize) return
    
    // 按最后使用时间排序，移除最旧的项
    const entries = Array.from(this.imageCache.entries())
    entries.sort((a, b) => a[1].lastUsed - b[1].lastUsed)
    
    const toRemove = entries.slice(0, entries.length - this.maxCacheSize)
    for (const [url] of toRemove) {
      this.imageCache.delete(url)
    }
  }
  
  // 获取资源URL
  private getAssetUrl(assetId: string): string | null {
    // TODO: 从资源管理器获取URL
    return null
  }
  
  // 更新性能统计
  private updateStats() {
    const now = performance.now()
    this.stats.frameTime = now - this.frameStartTime
    this.frameCount++
    
    // 每秒更新一次FPS
    if (now - this.lastFpsUpdate >= 1000) {
      this.stats.fps = this.frameCount
      this.frameCount = 0
      this.lastFpsUpdate = now
    }
  }
  
  // 获取性能统计
  getStats(): RenderStats {
    return { ...this.stats }
  }
  
  // 调整画布尺寸
  resize(width: number, height: number) {
    this.config.width = width
    this.config.height = height
    this.setupCanvas()
  }
  
  // 更新配置
  updateConfig(config: Partial<RenderConfig>) {
    Object.assign(this.config, config)
    this.setupCanvas()
  }
  
  // 导出画布为图片
  exportAsImage(format: 'png' | 'jpeg' = 'png', quality = 0.9): string {
    return this.canvas.toDataURL(`image/${format}`, quality)
  }
  
  // 导出画布为Blob
  exportAsBlob(format: 'png' | 'jpeg' = 'png', quality = 0.9): Promise<Blob | null> {
    return new Promise(resolve => {
      this.canvas.toBlob(resolve, `image/${format}`, quality)
    })
  }
  
  // 点击检测
  hitTest(x: number, y: number, layers: LayerData[]): LayerData | null {
    // 按z-index倒序检测（从上到下）
    const sortedLayers = [...layers]
      .filter(layer => layer.visible)
      .sort((a, b) => b.zIndex - a.zIndex)
    
    for (const layer of sortedLayers) {
      if (this.isPointInLayer(x, y, layer)) {
        return layer
      }
    }
    
    return null
  }
  
  // 检测点是否在图层内
  private isPointInLayer(x: number, y: number, layer: LayerData): boolean {
    const { position, scale, rotation } = layer
    
    // 简单的矩形碰撞检测（不考虑旋转）
    const size = 100 // 默认图层大小
    const halfWidth = (size * scale.x) / 2
    const halfHeight = (size * scale.y) / 2
    
    return (
      x >= position.x - halfWidth &&
      x <= position.x + halfWidth &&
      y >= position.y - halfHeight &&
      y <= position.y + halfHeight
    )
  }
  
  // 清理资源
  dispose() {
    this.imageCache.clear()
  }
}
